package com.cloud.wms.ui.data.presenter;

import com.cloud.core.base.BaseRxPresenter;
import com.cloud.core.utils.FileUtil;
import com.cloud.core.utils.MessageCreator;
import com.cloud.wms.app.FineExApplication;
import com.cloud.wms.http.Params;
import com.cloud.wms.http.observer.LoadingObserver;
import com.cloud.wms.http.observer.ResponseWrapper;
import com.cloud.wms.tools.RxUtils;
import com.cloud.wms.ui.data.contract.UploadImgContract;
import com.cloud.wms.ui.main.entity.LoginCache;
import com.cloud.wms.utils.EnvironmentUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Response;
import top.zibin.luban.Luban;


/**
 * @Author:Chen
 * @Date: 2021-01-14 15:51
 * @Description:
 */
public class UploadImgPresenter extends BaseRxPresenter<UploadImgContract.View> implements UploadImgContract.Presenter {
    // 10M
    public static final long MAX_FILE_LENGTH = 20 * 1024 * 1024;
    public static final int ORDER_CHECK = 0x101;
    public static final int IMG_UPLOAD = 0x102;

    @Inject
    public UploadImgPresenter() {

    }

    @Override
    public void checkOrderCode(String code, String typeCode) {
        Params params = Params.newInstance(Params.Type.WAREHOUSE);
        params.put("Code", code);
        params.put("Type", typeCode);
        params.put("userID", LoginCache.getInstance().getUserInfo().getUserID());
        FineExApplication
                .component()
                .http()
                .uploadImg(params)
                .map(new ResponseWrapper<>())

//        Observable.timer(1000, TimeUnit.MILLISECONDS)
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, ORDER_CHECK));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }

    @Override
    public void uploadImg(String code, String typeCode, List<String> images) {
        Observable.just(images)
                .flatMap((Function<List<String>, ObservableSource<List<File>>>) strings -> {
                    try {
                        FileUtil.clearAllFile(EnvironmentUtils.getPath());
                        return Observable.just(Luban.with(mView.provideContext())
                                .setTargetDir(EnvironmentUtils.getPath())
                                .ignoreBy(1024)
                                .load(strings)
                                .get());
                    } catch (Exception e) {
                        return Observable.error(e);
                    }
                })
                .flatMap((Function<List<File>, Observable<MultipartBody.Part[]>>) files -> {
                    ArrayList<MultipartBody.Part> parts = new ArrayList<>();
                    long sumSize = 0;
                    for (int i = 0; i < files.size(); i++) {
                        if (files.get(i).exists() && files.get(i).isFile()) {
                            RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), files.get(i));
                            MultipartBody.Part body = MultipartBody.Part.createFormData("Img", files.get(i).getName(), requestBody);
                            parts.add(body);
                            sumSize += files.get(i).length();
                        }
                    }
                    if (sumSize > MAX_FILE_LENGTH) {
                        return Observable.error(new Throwable("超出最大文件上传限制，请跟分批上传"));
                    }
                    return Observable.just(parts.toArray(new MultipartBody.Part[parts.size()]));
                })
                .flatMap((Function<MultipartBody.Part[], Observable<Response<Object>>>) parts -> {

                    Params params = Params.newInstance(Params.Type.WAREHOUSE);
                    params.put("Code", code);
                    params.put("Type", typeCode);
                    params.put("userID", LoginCache.getInstance().getUserInfo().getUserID());
                    return FineExApplication
                            .component()
                            .http()
                            .uploadImg(params, parts);
                })
                .map(new ResponseWrapper<>())

//        Observable.timer(1000, TimeUnit.MILLISECONDS)
                .compose(mView.toLifecycle())
                .compose(RxUtils.threadSwitch())
                .subscribe(new LoadingObserver<Object>(mView.provideContext()) {
                    @Override
                    public void onSuccess(Object info) {
                        mView.onSuccess(MessageCreator.createMessage(info, IMG_UPLOAD));
                    }

                    @Override
                    public void onError(String msg) {
                        mView.error(msg);
                    }
                });
    }
}
